﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace comm.world
{
    public abstract class BObject
    {
        class T
        {
            public double Millisecond { get; set; }
            public bool IsTimeout { get; set; }
            public comm.Timing Timing { get; set; }
            public Action<int> Callback = null;
        }

        comm.UniqueID _uid = new UniqueID();
        Dictionary<string, T> _timingDic = new Dictionary<string, T>();

        public BObject()
        {
        }

        public string Timeout(double millisecond, Action<int> callback)
        {
            lock (_timingDic)
            {
                var id = _uid.NewId();
                _timingDic.Add(id, new T
                {
                    IsTimeout = true,
                    Millisecond = millisecond,
                    Timing = new comm.Timing(),
                    Callback = callback
                });
                return id;
            }
        }
        public string Timing(double millisecond, Action<int> callback)
        {
            lock (_timingDic)
            {
                var id = _uid.NewId();
                _timingDic.Add(id, new T
                {
                    IsTimeout = false,
                    Millisecond = millisecond,
                    Timing = new comm.Timing(),
                    Callback = callback
                });
                return id;
            }
        }
        public void CancelTiming(string id)
        {
            lock (_timingDic)
            {
                if (_timingDic.ContainsKey(id))
                {
                    _timingDic.Remove(id);
                }
            }
        }

        public void Update(comm.TimeStat timeStat)
        {
            lock (_timingDic)
            {
                var delList = new List<string>();
                foreach (var key in _timingDic.Keys)
                {
                    var timing = _timingDic[key];
                    var c = timing.Timing.GetElapsedTime(timeStat, timing.Millisecond);
                    if (c > 0)
                    {
                        timing.Callback(c);
                        if (timing.IsTimeout)
                        {
                            delList.Add(key);
                        }
                    }
                }
                foreach (var key in delList)
                {
                    _timingDic[key].Callback = null;
                    _timingDic.Remove(key);
                }
            }

            OnUpdate(timeStat);
        }

        protected abstract void OnUpdate(comm.TimeStat timeStat);
    }
}
